using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;

namespace LiveLinq.Internal
{
	abstract class QueryResultBase<TSource>
	{
		protected IEnumerable<TSource> _source;
		protected INotifyCollectionChanged _sourceNotifiableCollection;
		// protected INotifyPropertyChanged _sourceNotifiableObject;
		protected readonly List<TSource> _attached = new List<TSource>();

		// protected ObservableCollectionQueryResultBase() {}

		protected QueryResultBase(IEnumerable<TSource> source)
		{
			_source = source;
			_sourceNotifiableCollection = source as INotifyCollectionChanged ?? NullNotifyCollectionChanged.Instance;
			// _sourceNotifiableObject = source as INotifyPropertyChanged ?? NullNotifyPropertyChanged.Instance;
			_sourceNotifiableCollection.CollectionChanged += Source_CollectionChanged;
		}

		protected void Source_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
		{
			switch (e.Action)
			{
				case NotifyCollectionChangedAction.Add:
				case NotifyCollectionChangedAction.Move:
				case NotifyCollectionChangedAction.Remove:
				case NotifyCollectionChangedAction.Replace:
				case NotifyCollectionChangedAction.Reset:
				default:
					OnSourceReset();
					break;
			}
		}

		protected abstract void OnSourceReset();

		protected void DetachItem(TSource item)
		{
			var nitem = item as INotifyPropertyChanged;
			if (nitem != null)
			{
				nitem.PropertyChanged -= Item_PropertyChanged;
			}
		}

		protected void AttachItem(TSource item)
		{
			_attached.Add(item);
			var nitem = item as INotifyPropertyChanged;
			if (nitem != null)
			{
				nitem.PropertyChanged += Item_PropertyChanged;
			}
		}

		protected abstract void Item_PropertyChanged(object sender, PropertyChangedEventArgs e);
	}
}